package org.sxp.common.utils.datax.reader;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.sxp.common.dto.datax.reader.DataXRDMSReader;
import org.sxp.common.exception.BusinessException;
import org.sxp.common.utils.SpringContextUtils;
import org.sxp.modules.datasource.entity.DatabaseDO;
import org.sxp.modules.datasource.service.DatabaseService;
import org.sxp.modules.dataworks.dto.SyncDTO;
import org.sxp.modules.dataworks.entity.SyncDO;
import org.sxp.modules.dataworks.service.SyncService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Reader
 *
 * @author zhouhongfa@gz-yibo.com
 * @ClassName BaseReaderPlugin
 * @Version 1.0
 * @since 2019/8/2 16:27
 */
public abstract class BaseReader implements IDataxReader {

    public static final String SELECT_ = "select ";
    public static final String _FROM = " from";
    public static final String END = "end,";
    public static final String FROM = "from";
    private String name;

    protected SyncDTO syncDTO;

    protected final Pattern pattern = Pattern.compile("\"reader\":(\\{.*),\"writer\"");

    public BaseReader(SyncDTO syncDTO){
        this.syncDTO = syncDTO;
    }

    @Override
    public Map<String, Object> build() {
        DatabaseService databaseService = SpringContextUtils.getBean(DatabaseService.class);
        DatabaseDO jobDatasource = databaseService.getById(syncDTO.getSourceDb());
        Map<String, Object> readerObj = Maps.newLinkedHashMap();
        readerObj.put("name", getName());
        List<String> columnList = new ArrayList<>();
        for (JSONObject columnObj : syncDTO.getSourceField()) {
            columnList.add(columnObj.getString("name"));
        }
        Map<String, Object> parameterObj = Maps.newLinkedHashMap();
        Map<String, Object> connectionObj = Maps.newLinkedHashMap();

        parameterObj.put("username", jobDatasource.getUsername());
        parameterObj.put("password", jobDatasource.getPassword());
        parameterObj.put("splitPk", syncDTO.getSplitPk());

        //判断是否是 querySql
        if (StrUtil.isNotBlank(syncDTO.getQuerySql())) {
            syncDTO.setQuerySql(syncDTO.getQuerySql().trim());
            querySqlCheck(syncDTO.getQuerySql());
            connectionObj.put("querySql", ImmutableList.of("select " + String.join(",", columnList) + " from ("+syncDTO.getQuerySql()+") a"));
        } else {
            parameterObj.put("column", columnList);
            //判断是否有where
            if (StrUtil.isNotBlank(syncDTO.getWhereSql())) {
                parameterObj.put("where", syncDTO.getWhereSql());
            }
            connectionObj.put("table", new String[]{syncDTO.getSourceTable()});
        }

        connectionObj.put("jdbcUrl", ImmutableList.of(jobDatasource.getUrl()));
        parameterObj.put("connection", ImmutableList.of(connectionObj));
        readerObj.put("parameter", parameterObj);
        afterBuild(jobDatasource, readerObj);
        return readerObj;
    }

    protected void afterBuild(DatabaseDO jobDatasource, Map<String, Object> readerObj) throws BusinessException{
        /**
         * 用于继承类自定义处理部分
         */
    }

    private String querySqlCheck(String querySql) throws BusinessException{
        String sql = querySql.toLowerCase().trim();
        if(!sql.startsWith(SELECT_)){
            throw new BusinessException("自定义SQL必须以【select+空格】关键字开头，注意回车换行及空格!");
        }
        int index = sql.indexOf(StrUtil.C_LF+FROM);
        if(index == -1){
            index = sql.indexOf(StrUtil.CRLF+ FROM);
        }
        if(index > -1){
            throw new BusinessException("自定义SQL关键字【空格与form之间】不能回车换行!");
        }
        // 校验case end后必须带别名
        if(sql.contains(StrUtil.C_SPACE+END) || sql.contains(StrUtil.CR+END) || sql.contains(StrUtil.CRLF+END)){
            throw new BusinessException("自定义SQL关键字【case end】后面必须带别名，不能直接逗号结束!");
        }
        // 截取select空格与空格form关键字之间的列
        String temp = sql.substring(sql.indexOf(SELECT_), sql.indexOf(_FROM));
//        if(temp.contains()){
//
//        }
        return null;
    }

    @Override
    public void backBuild() {
        String removeSpace = StrUtil.trim(syncDTO.getDataxJson());
        /*
         * 根据key和josn字符串取出特定的value :{"(.*?)"}
         */
        Matcher matcher = pattern.matcher(removeSpace);
        String value = null;
        if (matcher.find()) {
            value = matcher.group(1);
        }
        if(JSONUtil.isJson(value)){
//            DataXRDMSReader reader = JSON.parseObject(value, DataXRDMSReader.class);
//            List<String> querySql = reader.getParameter().getConnection().get(0).getQuerySql();
//            syncDTO.setQuerySql(ArrayUtil.isNotEmpty(querySql) ? querySql.get(0) : null);
        }
    }
}
